/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

package com.huawei.housekeeper.common.utils;

import com.huawei.housekeeper.common.exception.Assert;

import com.google.common.base.Charsets;
import com.google.common.io.CharStreams;
import com.nimbusds.jose.jwk.JWK;
import com.nimbusds.jose.jwk.JWKSet;

import lombok.extern.slf4j.Slf4j;

import org.jose4j.jwk.JsonWebKey;
import org.jose4j.jwk.PublicJsonWebKey;
import org.jose4j.jwk.RsaJsonWebKey;
import org.jose4j.lang.JoseException;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.text.ParseException;
import java.util.List;

/**
 * Jwk工具类
 *
 * @author y84241604
 * @since 2022-06-06
 */
@Slf4j
public class JwkUtil {

    private static final String KEYSTORE_PATH = "keystore.jwks";

    /**
     * 根据jwk获取PrivateKey
     *
     * @return PrivateKey
     */
    public static PrivateKey getPrivateKeyByJwk() {
        PrivateKey privateKey = null;

        try {
            privateKey = RsaJsonWebKey.Factory.newPublicJwk(getPublicJsonWebKey()).getPrivateKey();
        } catch (JoseException e) {
            log.error(e.getMessage(), e);
        }
        return privateKey;

    }

    /**
     * 根据jwk获取PrivateKey
     *
     * @return PrivateKey
     */
    private static String getPublicJsonWebKey() {
        JWKSet jwkSet = null;
        String jwks = null;
        String privateKeyString = null;
        try {
            InputStream is = JwkUtil.class.getClassLoader().getResourceAsStream(KEYSTORE_PATH);
            jwks = CharStreams.toString(new InputStreamReader(is, Charsets.UTF_8));
            Assert.notNull(jwks, "jwks read is null");
            jwkSet = JWKSet.parse(jwks);
            Assert.notNull(jwkSet, "error parse jwks is null");
            List<JWK> keys = jwkSet.getKeys();
            for (JWK key : keys) {
                PublicJsonWebKey jwk = RsaJsonWebKey.Factory.newPublicJwk(key.toString());
                privateKeyString = jwk.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE);
            }

        } catch (IOException e) {
            log.error(e.getMessage(), e);
        } catch (JoseException e) {
            log.error(e.getMessage(), e);
        } catch (ParseException e) {
            log.error(e.getMessage(), e);
        }

        return privateKeyString;
    }

    /**
     * 根据jwk获取 PublicKey
     *
     * @return PublicKey
     */
    public static PublicKey getPublicKeyByJwk() {

        PublicKey publicKey = null;

        try {
            publicKey = RsaJsonWebKey.Factory.newPublicJwk(getPublicJsonWebKey()).getPublicKey();
        } catch (JoseException e) {
            log.error(e.getMessage(), e);
        }
        return publicKey;
    }

}
